perm filename MGRAPH.PUB[HAL,HE]1 blob
sn#127024 filedate 1974-10-29 generic text, type T, neo UTF8
.gph:NEWSS GRAPH STRUCTURES
Attachments are stored in both the compiler and the runtime as a
graph structure. The nature of this structure is described
in {sssref rgf};
the algorithms which serve to extract values from a graph and
insert new values into it
can be found in Appendix II.
Suffice it here to say that if the value
of a variable is needed, and that value is marked as invalid, then
the list of calculator expressions for that variable is searched for
one which can compute a valid value; if none of the calculators will
work
(e.g. they all depend themselves on invalid values),
then the current (invalid) value is returned as the best answer
available. When a new value is assigned to a variable, all those
values whose calculators depend on the new value are marked as
invalid, so that the next time they are needed, graph searching is
performed. Building a graph structure therefore involves specifying
the calculators for all variables. Usually, this will be be done
implicitly by means of "intuitively obvious" statements like ATTACH
and DETACH. However, HAL also supplies primitives for explicit
manipulation of graph structure. The principal explicit means
employed for this purpose is the "graph assignment statement":
.UNFILL
<variable> <= <expression>
.REFILL
where "<=" may be read "is computed by". This construct causes
<expression> to be added to the list of calculators for <variable>.
Similarly,
.UNFILL
<variable> <%7≠%* <expression>
.REFILL
causes <expression> to be removed from the list of calculators, and
.UNFILL
<variable> <<= <expression>
.REFILL
replaces the current calculator list for <expression>. The statement
.UNFILL
<variable> <<= ;
.REFILL
would cause the calculator list to be set to null.
It is frequently very inconvenient to retype an entire expression in
order to remove it from the calculator list. HAL allows the user to
attach a name to an expression in a graph assignment statement by use
of the construct
.UNFILL
<variable> <= "id" <expression>
.REFILL
Then the construct
.UNFILL
<variable> <%7≠%* "id"
.REFILL
will remove the named expression from the calculator list. For
instance,
.UNFILL
F1 <= "foo" T*F2;
:
F1 <%7≠%* "foo";
.REFILL
would have the same effect as
.UNFILL
F1 <= T*F2;
:
F1 <%7≠%* T*F2;
.REFILL
In addition to the calculator list, a list of "updater" routines is
associated with every variable. These routines are executed whenever
the variable value is changed. Initially, the list of updaters is
null. However, the construct
.UNFILL
WHEN CHANGING <variable> ALSO DO "<id>" <statement>;
.REFILL
will cause <statement> to be added to the list of updaters for
<variable>. ("<id>" is optional, but is necessary if the <statement>
is ever to be removed from the updater list.) In <statement>, the
reserved words OLD and NEW may be used to refer to the old and new
values of var, respectively. For instance:
.UNFILL
WHEN CHANGING F2 ALSO DO "foo" F1α←NEW*(OLDα→F1);
.REFILL
Updaters may be removed from the updater list by the statement
.UNFILL
WHEN CHANGING <variable> DONT DO "<id>"
.REFILL
For our above example, this would be
.UNFILL
WHEN CHANGING F2 DONT DO "foo";
.REFILL
The form
.UNFILL
WHEN CHANGING <variable> ONLY DO <statement>;
.REFILL
replaces the updater list with one containing just <statement>, and
.UNFILL
WHEN CHANGING <variable> ONLY DO ;
.REFILL
clears the updater list completely. Since the attach structure makes
use of updater and calculator lists (see {sssref rgf}), careless use of the
replacement form is not advised.
One good use for updater routines is tracing. For example,
.UNFILL
WHEN CHANGING V ALSO DO
WRITE("The value of V is now ",NEW);
.REFILL
Details of the graph structure algorithms may be found in the appendix
on runtime routines.
One additional point that should be mentioned here is that the
updater routines for a variable are NOT called if the variable's
value is modified as a side effect of a change to some variable in
one of its calculators.
.gat: NEWSSS CONCERNING ATTACH AND DETACH
The ATTACH and DETACH statements are defined by their effects on the
graph structures.
.UNFILL
ATTACH F1 TO F2 BY T1
.UNFILL
is equivalent to
.REFILL
T1 α← F2α→F1;
F1 <= "xxx" T1 * F2;
WHEN CHANGING F1 ALSO DO "yyy" T1α←(F2α→NEW);
ASSERT FACT (ATTACHED F1 F2 T1);
Comment : For details of ASSERT see {sssref asr};
.REFILL
Then,
.UNFILL
DETACH F1 FROM F2;
.REFILL
is equivalent to
.UNFILL
F1 <%7≠%* "xxx";
WHEN CHANGING F1 DONT DO "yyy";
DENY FACT(ATTACHED F1 F2 ANYTHING);
ASSERT FACT (WAS_ATTACHED F1 F2);
.REFILL
Similarly,
.UNFILL
ATTACH F1 TO F2 BY T1 RIGIDLY
.REFILL
is equivalent to
.UNFILL
T1 α← F2α→F1;
F1 <= T1 * F2;
F2 <= INVERSE(T1) * F1 .
.REFILL